package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.UserInfoTVO;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.service.*;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author げっしょく
 * @date 2021/11/2
 */
@Service
public class UsersService {

    @DubboReference
    private VisitorsApi visitorsApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private FriendApi friendApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private MessagesService messagesService;

    /**
     * 查看查询过我的用户（我的列表）
     *
     * @param page
     * @param pagesize
     * @param nickname
     * @return
     */
    public PageResult getLookMe(Integer page, Integer pagesize, String nickname) {
        //当前用户id
        Long userId = UserHolder.getId();


        String key = Constants.VISITORS_USER;
        String hashKey = userId.toString();
        //添加用户上一次查看时间
        Long l = System.currentTimeMillis();
        redisTemplate.opsForHash().put(key, hashKey, l.toString());

        //获得访问过我的用户并判断是否为空
        List<Visitors> list = visitorsApi.getPageLookMe(page, pagesize, userId);
        if (CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //取出访问过我用户的id
        List<Long> visitorUserId = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
        //通过id找出我对ta是否喜欢
        Map<Long, UserLike> map = userLikeApi.getLikes(visitorUserId, userId);
        //通过id找出用户详情
        UserInfo userInfo = new UserInfo();
        if (!StringUtils.isEmpty(nickname)) {
            userInfo.setNickname(nickname);
        }
        Map<Long, UserInfo> byUserIds = userInfoApi.getByUserIds(visitorUserId, userInfo);
        //通过id找出我与对方的缘分值
        Map<Long, RecommendUser> re = recommendUserApi.getUsers(visitorUserId, userId);
        //遍历集合
        List<UserInfoTVO> vos = new ArrayList<>();
        for (Long id : visitorUserId) {
            UserInfo userInfo1 = byUserIds.get(id);
            if (userInfo1 != null) {
                UserLike userLike = map.get(id);
                Boolean isLike = false;
                if (!ObjectUtil.isEmpty(userLike)) {
                    isLike = userLike.getIsLike();
                }
                RecommendUser recommendUser = re.get(id);
                Double score = RandomUtil.randomDouble(60.0, 95.6);
                if (ObjectUtil.isNotEmpty(recommendUser)) {
                    score = recommendUser.getScore();
                }
                UserInfoTVO vo = UserInfoTVO.init(userInfo1, isLike, score);
                vos.add(vo);
            }
        }
        return new PageResult(page, pagesize, 0L, vos);
    }

    //从redis中查询我喜欢的用户id
//    public


    //查询相互喜欢
    public PageResult getLikeMutually(Integer page, Integer pagesize, String nickname) {
        //从redis中查询出我喜欢的用户
        Set<String> members = getLikeUserIds();
        //判断从reids中取出来的数据是否为空
        if (CollUtil.isEmpty(members)) {

            return new PageResult();
        }
        //遍历set集合
        List<Long> userIds = members.stream().map(m -> Long.valueOf(m)).collect(Collectors.toList());
        //通过用户set集合去查找喜欢我的并返回
        List<UserLike> likes = userLikeApi.getWhoLoveMe(userIds, UserHolder.getId());
        //判断找到的数据是否为空
        if (CollUtil.isEmpty(likes)) {
            return new PageResult();
        }
        //取出数据(喜欢我的)中的用户id
        List<Long> userLikes = likes.stream().map(like -> like.getUserId()).collect(Collectors.toList());
        //通过用户id和条件去查询用户信息
        Map<Long, UserInfo> map = userInfoApi.getByUserIds(userLikes, null);
        //通过用户id去查询和我缘分值
        Map<Long, RecommendUser> users = recommendUserApi.getUsers(userIds, UserHolder.getId());
        //通过用户id去查询是否喜欢他, 因为当前是查询的互相喜欢,所以全是true
        return getPageResult(page, pagesize, userLikes, map, users);
    }


    //用户封装我喜欢和互相喜欢的数据
    private PageResult getPageResult(Integer page, Integer pagesize, List<Long> userLikes, Map<Long, UserInfo> map, Map<Long, RecommendUser> users) {
        List<UserInfoTVO> vos = new ArrayList<>();
        for (Long userLike : userLikes) {
            UserInfo userInfo = map.get(userLike);
            if (userInfo != null) {
                RecommendUser recommendUser = users.get(userLike);
                Double score = null;
                if (recommendUser != null) {
                    score = recommendUser.getScore();
                } else {
                    score = RandomUtil.randomDouble(60.5, 89.6);
                }
                UserInfoTVO vo = UserInfoTVO.init(userInfo, true, score);
                vos.add(vo);
            }
        }
        //封装数据
        return new PageResult(page, pagesize, Long.valueOf(vos.size()), vos);
    }

    //从redis中获取我喜欢的用户id
    private Set<String> getLikeUserIds() {
        //从redis中查询出我喜欢的用户
        String key = Constants.USER_LIKE_KEY + UserHolder.getId();
        return redisTemplate.opsForSet().members(key);
    }


    //查看我喜欢的
    public PageResult getMeLikeWho(Integer page, Integer pagesize, String nickname) {
        //从redis中读取我喜欢的用户id
        Set<String> likeUserIds = getLikeUserIds();
        if (CollUtil.isEmpty(likeUserIds)) {
            return new PageResult();
        }
        List<Long> userIds = likeUserIds.stream().map(u -> Long.valueOf(u)).collect(Collectors.toList());
        //通过用户查询用户详情
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setNickname(nickname);
        Map<Long, UserInfo> map = userInfoApi.getByUserIds(userIds, userInfo1);
        //通过用户id查询我和他缘分值
        Map<Long, RecommendUser> users = recommendUserApi.getUsers(userIds, UserHolder.getId());
        //查询我是否喜欢他(省略: 因为从redis中取出来的都是喜欢的)
        //封装数据并返回
        return getPageResult(page, pagesize, userIds, map, users);

    }

    //查询粉丝
    public PageResult getFans(Integer page, Integer pagesize, String nickname) {
        Long id = UserHolder.getId();
        //从redis中查询出我喜欢的用户
        String key = Constants.USER_LIKE_KEY + id;

        //获取喜欢我的用户的列表
        List<UserLike> likeMe = userLikeApi.getLikeMe(id);
        //判断找到的数据是否为空
        if (CollUtil.isEmpty(likeMe)) {
            return new PageResult();
        }
        //取出数据(喜欢我的)中的用户id
        List<Long> userLikes = likeMe.stream().map(like -> like.getUserId()).collect(Collectors.toList());
        //通过用户id和条件去查询用户信息
        UserInfo info = new UserInfo();
        info.setNickname(nickname);
        Map<Long, UserInfo> map = userInfoApi.getByUserIds(userLikes, info);
        List<UserInfoTVO> vos = new ArrayList<>();
        for (Long userLike : userLikes) {
            UserInfo userInfo = map.get(userLike);
            Boolean member = redisTemplate.opsForSet().isMember(key, userInfo.getId().toString());
            if (userInfo != null) {
                UserInfoTVO vo = UserInfoTVO.init(userInfo, member, null);
                vos.add(vo);
            }
        }
        return new PageResult(page, pagesize, 0L, vos);
    }

    /**
     * 粉丝-喜欢
     *
     * @param uid
     */
    public void fansLike(Long uid) {
        Long id = UserHolder.getId();
        Boolean flag = userLikeApi.fansLike(id, uid);
        if (flag == true) {
            redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + id, uid.toString());
            messagesService.addFriend(uid);
        }
    }

    /**
     * 取消用户喜欢
     * @param uid
     */
    public void deleteLikeUser(Long uid) {
        //首先删除数据库中的数据
        boolean flag = userLikeApi.deleteLikeUser(uid,UserHolder.getId());
        if (!flag){
            throw new BusinessException(ErrorResult.error());
        }
        //删除redis中的数据
        String key = Constants.USER_LIKE_KEY+UserHolder.getId();
        redisTemplate.opsForSet().remove(key,uid.toString());

    }


}
